WebUI (NUI Light) - Developer Documentation

Welcome to the developer documentation for the WebUI API (compatible version). WebUI allows GTA V mod developers to create immersive, web-based user interfaces (HTML/CSS/JS) directly within the game using CEF (Chromium Embedded Framework).

This documentation covers both the C# (ScriptHookVDotNet) backend API and the JavaScript frontend SDK.


Table of Contents


1. Architecture Overview

WebUI operates on a multi-layer architecture:


2. C# API Reference

Namespace: WebUI
Class: API (Inherits from Script)

The C# API provides a static interface to create, manage, and communicate with web layers.

Lifecycle Management

bool CreateLayer(int id, string url, bool visible = false)

Creates a new UI layer.

void Reload(int id)

Reloads the current URL for the specified layer.

void Close(int id)

Closes and destroys the specified layer.

void CloseAll()

Closes and destroys all active layers.

Visibility & Input Focus

void SetVisible(int id, bool state)

Shows or hides the specified layer.

void SetFocus(int id, bool captureKeyboard, bool captureMouse)

Sets input focus to a specific layer. This also activates global input traps so the game doesn't process the inputs while the UI is focused.

void SetClickThrough(int id, bool passInputsToGame)

Allows mouse clicks to pass through the UI directly into the game world (useful for HUDs).

void CaptureMouseInput(bool toggle)

Globally forces mouse input capture for WebUI.

void CaptureKeyboardInput(bool toggle)

Globally forces keyboard input capture for WebUI.

Z-Order & Layout

void SetZOrder(int id, int order)

Explicitly sets the Z-Order (depth/stacking order) of a layer.

void SendToFront(int id)

Brings the specified layer to the very front of all UI layers.

void SendToBack(int id)

Sends the specified layer to the very back of all UI layers.

Communication (C# to JS)

void SendMessage(int id, string eventName, object payloadData)

Sends a JSON-serializable payload to the specified layer. The JavaScript side can listen for this using WebUI.listen().

void ExecuteJS(int id, string javascriptPayload)

Executes raw JavaScript code directly in the context of the layer's webpage.

Events (JS to C#)

event WebUIEventHandler OnMessageReceived

A static C# event that triggers when the JavaScript side emits data back to C#.

Delegate Signature:

public delegate void WebUIEventHandler(int layerId, string eventName, dynamic parsedPayload);

3. JavaScript SDK Reference

To communicate with the C# backend, include the WebUI_SDK.js in your HTML file. It exposes a global window.WebUI object.

WebUI.listen(eventName, callback)

Listens for messages sent from the C# backend via API.SendMessage().

WebUI.listen("UPDATE_SCORE", function(payload) {
    console.log("New score: " + payload.score);
});

WebUI.emit(eventName, data = {})

Sends data from the webpage to the C# backend. Triggers the OnMessageReceived event in C#.

WebUI.emit("PLAYER_READY", { username: "JohnDoe" });

WebUI.ready()

Highly Recommended. Emits a built-in system event (SYSTEM_LAYER_READY) telling C# that the HTML/DOM framework (Vue, React, Svelte, etc.) is fully loaded and ready to receive initialization data.

window.addEventListener('DOMContentLoaded', (event) => {
    WebUI.ready();
});

WebUI.dropFocus()

Emits a built-in system event (SYSTEM_DROP_FOCUS) that forces the C# engine to release keyboard/mouse input capture. This allows the player to move the GTA V camera again without closing the UI.

document.getElementById('backBtn').addEventListener('click', () => {
    WebUI.dropFocus();
});

WebUI.close()

Emits a built-in system event (SYSTEM_CLOSE_LAYER) instructing C# to destroy/hide the current layer.

document.getElementById('exitBtn').addEventListener('click', () => {
    WebUI.close();
});

4. System Built-in Events

The WebUI backend natively listens for the following events emitted from JS via WebUI.emit():

Event Name Description
SYSTEM_LAYER_READY Notifies C# that the webpage is loaded and ready for data injection.
SYSTEM_DROP_FOCUS Releases hardware input capture (keyboard/mouse) back to GTA V.
SYSTEM_CLOSE_LAYER Triggers API.Close(id) on the C# side for the emitting layer.

5. Usage Example

HTML / JavaScript Side (ui.html)

<!DOCTYPE html>
<html>
<head>
    <title>My WebUI</title>
    <script src="WebUI_SDK.js"></script>
</head>
<body>
    <h1 id="title">Hello GTA V!</h1>
    <button onclick="returnToGame()">Release Focus</button>

    <script>
        // 1. Tell C# we are ready
        WebUI.ready();

        // 2. Listen for data from C#
        WebUI.listen("SET_TITLE", function(payload) {
            document.getElementById('title').innerText = payload.newTitle;
        });

        // 3. Send data to C#
        function returnToGame() {
            WebUI.emit("BUTTON_CLICKED", { buttonId: 1 });
            WebUI.dropFocus(); // Let the player move the camera again
        }
    </script>
</body>
</html>

C# Side (MyMod.cs)

using System;
using GTA;
using WebUI;

public class MyWebUIMod : Script
{
    private const int UI_ID = 1;
    private string url = "file:///C:/MyMod/ui.html";

    public MyWebUIMod()
    {
        // Subscribe to JS events
        API.OnMessageReceived += HandleWebUIEvent;

        // Create and show the layer
        API.CreateLayer(UI_ID, url, true);
        
        // Capture input so the user can interact with the webpage
        API.SetFocus(UI_ID, true, true);
    }

    private void HandleWebUIEvent(int layerId, string eventName, dynamic parsedPayload)
    {
        if (layerId != UI_ID) return;

        if (eventName == "BUTTON_CLICKED")
        {
            GTA.UI.Notification.Show($"Button {parsedPayload.buttonId} was clicked!");
        }
    }

    private void OnTick(object sender, EventArgs e)
    {
        // Example: Send data to JS when a specific key is pressed
        if (Game.IsKeyPressedJustPressed(Keys.Y))
        {
            API.SendMessage(UI_ID, "SET_TITLE", new { newTitle = "Key Y was pressed!" });
        }
    }
}